{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
    "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
    "execution": {
     "iopub.execute_input": "2025-02-19T10:02:09.851626Z",
     "iopub.status.busy": "2025-02-19T10:02:09.851440Z",
     "iopub.status.idle": "2025-02-19T10:02:22.506110Z",
     "shell.execute_reply": "2025-02-19T10:02:22.505438Z",
     "shell.execute_reply.started": "2025-02-19T10:02:09.851607Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import random\n",
    "import shutil\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D, Dense, Dropout\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.optimizers import Adam"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:02:30.655569Z",
     "iopub.status.busy": "2025-02-19T10:02:30.655251Z",
     "iopub.status.idle": "2025-02-19T10:02:31.307180Z",
     "shell.execute_reply": "2025-02-19T10:02:31.306401Z",
     "shell.execute_reply.started": "2025-02-19T10:02:30.655544Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using device: /GPU:0\n"
     ]
    }
   ],
   "source": [
    "def get_default_device():\n",
    "    \"\"\"Pick GPU if available, else CPU\"\"\"\n",
    "    if tf.config.list_physical_devices('GPU'):\n",
    "        return \"/GPU:0\"\n",
    "    else:\n",
    "        return \"/CPU:0\"\n",
    "\n",
    "device = get_default_device()\n",
    "print(f\"Using device: {device}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:25:31.152363Z",
     "iopub.status.busy": "2025-02-19T10:25:31.152018Z",
     "iopub.status.idle": "2025-02-19T10:25:31.155880Z",
     "shell.execute_reply": "2025-02-19T10:25:31.154989Z",
     "shell.execute_reply.started": "2025-02-19T10:25:31.152336Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "train_path = '/kaggle/input/ecg-image-data/ECG_Image_data/train'\n",
    "test_path = '/kaggle/input/ecg-image-data/ECG_Image_data/test'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:25:33.163050Z",
     "iopub.status.busy": "2025-02-19T10:25:33.162775Z",
     "iopub.status.idle": "2025-02-19T10:26:12.051829Z",
     "shell.execute_reply": "2025-02-19T10:26:12.051150Z",
     "shell.execute_reply.started": "2025-02-19T10:25:33.163030Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "Found 98557 images belonging to 5 classes.\n",
      "Found 24638 images belonging to 5 classes.\n"
     ]
    }
   ],
   "source": [
    "all_classes = os.listdir(train_path)\n",
    "classes_to_include = [cls for cls in all_classes if cls != \"F\"]\n",
    "\n",
    "# Data generators\n",
    "train_datagen = ImageDataGenerator(rescale=1./255,\n",
    "                                   shear_range=0.2,\n",
    "                                   zoom_range=0.2,\n",
    "                                   horizontal_flip=True)\n",
    "print(True)\n",
    "\n",
    "train_df = train_datagen.flow_from_directory(train_path,\n",
    "                                             target_size=(224, 224),\n",
    "                                             batch_size=32,\n",
    "                                             class_mode='categorical',\n",
    "                                             classes=classes_to_include)\n",
    "\n",
    "test_datagen = ImageDataGenerator(rescale=1./255)\n",
    "\n",
    "test_df = test_datagen.flow_from_directory(test_path,\n",
    "                                           target_size=(224, 224),\n",
    "                                           batch_size=32,\n",
    "                                           class_mode='categorical',\n",
    "                                           classes=classes_to_include)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:31:05.151678Z",
     "iopub.status.busy": "2025-02-19T10:31:05.151386Z",
     "iopub.status.idle": "2025-02-19T10:31:05.460153Z",
     "shell.execute_reply": "2025-02-19T10:31:05.459172Z",
     "shell.execute_reply.started": "2025-02-19T10:31:05.151658Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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3Y5ly5YhIyOj3vtfak25/FxmsxnLly+vtV9ZWRmsVmutbT179oRSqazV9+hKV76mp02bhszMTHzwwQd19jUajaisrHT4WO52+etXEAS8/fbb0Gg0GD16NIDmvc79/Pyc9nftDCqVCgqFotbKM6mpqU5draSh8wJ1X+uvv/56i4956Xl+8803nXbMS8aOHYuAgAA8//zz9faNy8/PB3BxTlaTyVTrtsTERPj7+9d6/TbndXDkyJF6rwikpaXh5MmTNcVuREQERo0ahf/+97/Izs5uMOOl8wN138eLi4vr/E7E/vuji9gCKBHr169HUlISrFYrcnNzsXXrVmzatAkJCQn48ccfG51cdenSpdixYwcmTJiAhIQE5OXlYfny5YiLi6vp+J+YmIigoCC899578Pf3h5+fHwYOHNhgH56mhISEYNiwYbjzzjuRm5uL119/HR06dKg1Vc38+fPx7bffYty4cZg2bRpSUlLw2Wef1elP05xsN954I6655ho8+eSTSE1NxVVXXYWNGzfihx9+wEMPPVTn2C11zz334L///S/mzp2LAwcOoG3btvj222+xe/duvP76660aKJGZmVnzrf1yBoOhZjWHIUOG4J133sH999+PLl261FoJZPv27fjxxx9rWsoA4LPPPsO4ceNw8803Y/z48bjuuusQHBxcsxLIjh07HCqOly1bhpSUFCxcuBBr1qzBxIkTERwcjPT0dHzzzTdISkrCjBkz6r3vkCFDEBwcjDlz5mDhwoVQKBRYtWpVnTf/rVu34sEHH8TUqVPRqVMnWK1WrFq1CiqVClOmTAHg2Gv69ttvx+rVq3Hvvfdi27ZtGDp0KGw2G5KSkrB69Wps2LAB/fv3d+hY7qTX6/Hrr79izpw5GDhwINavX49ffvkFTzzxRM0UQs15nffr1w+bN2/Gq6++ipiYGLRr1w4DBw50++O6ZMKECXj11Vcxbtw4zJo1C3l5eXjnnXfQoUMHHD161GXnDQgIqOkfZ7FYEBsbi40bNzbYAu2I3r17Y+bMmVi+fDlKS0sxZMgQbNmyBcnJyU7J++677+L2229H3759MWPGDISHhyM9PR2//PILhg4dirfffhtnzpzB6NGjMW3aNHTr1g1qtRrff/89cnNza/0t9uvXD++++y6ee+45dOjQARERETUDoq60adMmLF68GJMmTcKgQYNgMBhw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",
      "text/plain": [
       "<Figure size 800x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "def Count_Samples(dataset_path):\n",
    "    class_counts = {}\n",
    "    for class_name in os.listdir(dataset_path):\n",
    "        class_folder = os.path.join(dataset_path, class_name)\n",
    "        if os.path.isdir(class_folder):\n",
    "            class_counts[class_name] = len(os.listdir(class_folder))\n",
    "    \n",
    "    # Create the pie chart\n",
    "    plt.figure(figsize=(8, 8))\n",
    "    plt.pie(class_counts.values(), labels=class_counts.keys(), autopct='%1.1f%%', startangle=140)\n",
    "    plt.title(f\"Distribution of ECG Classes in both Train and Test Sets\")\n",
    "    plt.axis('equal')   \n",
    "    plt.show()\n",
    "\n",
    "Count_Samples(train_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:32:04.190404Z",
     "iopub.status.busy": "2025-02-19T10:32:04.190080Z",
     "iopub.status.idle": "2025-02-19T10:32:04.201999Z",
     "shell.execute_reply": "2025-02-19T10:32:04.201104Z",
     "shell.execute_reply.started": "2025-02-19T10:32:04.190368Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "def build_2d_cnn(input_shape, num_classes):\n",
    "    model = Sequential([\n",
    "    Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),\n",
    "    MaxPooling2D(pool_size=(2, 2)),\n",
    "    Conv2D(64, (3, 3), activation='relu'),\n",
    "    MaxPooling2D(pool_size=(2, 2)),\n",
    "    GlobalAveragePooling2D(),\n",
    "    Dense(64, activation='relu'),\n",
    "    Dropout(0.5),\n",
    "    Dense(num_classes, activation='softmax')\n",
    "    ])\n",
    "    model.compile(optimizer=Adam(),\n",
    "              loss='categorical_crossentropy',\n",
    "              metrics=['accuracy'])\n",
    "    return model\n",
    "\n",
    "def build_vgg16(input_shape, num_classes):\n",
    "    model = Sequential([\n",
    "        # Block 1\n",
    "        Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=input_shape),\n",
    "        Conv2D(32, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "\n",
    "        # Block 2\n",
    "        Conv2D(64, (3, 3), activation='relu', padding='same'),\n",
    "        Conv2D(64, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "\n",
    "        # Block 3\n",
    "        Conv2D(128, (3, 3), activation='relu', padding='same'),\n",
    "        Conv2D(128, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "\n",
    "        GlobalAveragePooling2D(),   \n",
    "        Dense(64, activation='relu'),   \n",
    "        Dropout(0.5),\n",
    "        Dense(num_classes, activation='softmax')   \n",
    "    ])\n",
    "    \n",
    "    model.compile(optimizer=Adam(learning_rate=0.001), \n",
    "                  loss='categorical_crossentropy', \n",
    "                  metrics=['accuracy'])\n",
    "    return model\n",
    "\n",
    "def build_vgg19(input_shape, num_classes):\n",
    "    model = Sequential([\n",
    "        # Convolutional Block 1\n",
    "        Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=input_shape),\n",
    "        Conv2D(64, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "        \n",
    "        # Convolutional Block 2\n",
    "        Conv2D(128, (3, 3), activation='relu', padding='same'),\n",
    "        Conv2D(128, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "        \n",
    "        # Convolutional Block 3\n",
    "        Conv2D(256, (3, 3), activation='relu', padding='same'),\n",
    "        Conv2D(256, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "        \n",
    "        # Global pooling and Dense layers\n",
    "        GlobalAveragePooling2D(),\n",
    "        Dense(64, activation='relu'),  \n",
    "        Dropout(0.5),\n",
    "        Dense(num_classes, activation='softmax')   \n",
    "    ])\n",
    "\n",
    "    model.compile(optimizer=Adam(),\n",
    "                  loss='categorical_crossentropy',\n",
    "                  metrics=['accuracy'])\n",
    "    \n",
    "    return model\n",
    "\n",
    "\n",
    "def build_resnet50(input_shape, num_classes):\n",
    "    model = Sequential([\n",
    "        \n",
    "        # Initial Convolutional Layer\n",
    "        Conv2D(64, (7, 7), strides=(2, 2), activation='relu', padding='same', input_shape=input_shape),\n",
    "        MaxPooling2D(pool_size=(3, 3), strides=(2, 2)),\n",
    "        \n",
    "        # Residual-like Blocks\n",
    "        Conv2D(64, (3, 3), activation='relu', padding='same'),\n",
    "        Conv2D(64, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "\n",
    "        Conv2D(128, (3, 3), activation='relu', padding='same'),\n",
    "        Conv2D(128, (3, 3), activation='relu', padding='same'),\n",
    "        MaxPooling2D(pool_size=(2, 2)),\n",
    "\n",
    "        GlobalAveragePooling2D(),\n",
    "        Dense(64, activation='relu'),  \n",
    "        Dropout(0.5),\n",
    "        Dense(num_classes, activation='softmax')  \n",
    "    ])\n",
    "    model.compile(optimizer=Adam(),\n",
    "                  loss='categorical_crossentropy',\n",
    "                  metrics=['accuracy'])\n",
    "    return model\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:32:49.949859Z",
     "iopub.status.busy": "2025-02-19T10:32:49.949572Z",
     "iopub.status.idle": "2025-02-19T10:32:49.955393Z",
     "shell.execute_reply": "2025-02-19T10:32:49.954360Z",
     "shell.execute_reply.started": "2025-02-19T10:32:49.949838Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# Training function\n",
    "def train_all_models(train_df, test_df):\n",
    "    IMAGE_SIZE = (224, 224, 3)\n",
    "    model_configs = [\n",
    "        {'type': '2d_cnn', 'func': build_2d_cnn},\n",
    "        {'type': 'vgg16', 'func': build_vgg16},\n",
    "        {'type': 'vgg19', 'func': build_vgg19},\n",
    "        {'type': 'resnet50', 'func': build_resnet50},\n",
    "    ]\n",
    "    \n",
    "    model_results = {}\n",
    "    for config in model_configs:\n",
    "        print(f\"\\n--- Training {config['type']} Model ---\")\n",
    "        # with strategy.scope():  # Use TPU distribution strategy\n",
    "        model = config['func']((224, 224, 3), len(classes_to_include))\n",
    "        model.summary()\n",
    "        history = model.fit(train_df,\n",
    "                            validation_data=test_df,\n",
    "                            epochs=10,\n",
    "                            verbose=1)\n",
    "        test_loss, test_accuracy = model.evaluate(test_df)\n",
    "        print(f\"Test Loss: {test_loss}\")\n",
    "        print(f\"Test Accuracy: {test_accuracy}\")\n",
    "        model_results[config['type']] = {'history': history}\n",
    "    return model_results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:33:25.944470Z",
     "iopub.status.busy": "2025-02-19T10:33:25.944162Z",
     "iopub.status.idle": "2025-02-19T10:33:25.949697Z",
     "shell.execute_reply": "2025-02-19T10:33:25.948789Z",
     "shell.execute_reply.started": "2025-02-19T10:33:25.944450Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "def plot_model_comparisons(model_results):\n",
    "    plt.figure(figsize=(15, 5))\n",
    "    plt.subplot(1, 2, 1)\n",
    "    for model_name, results in model_results.items():\n",
    "        plt.plot(results['history'].history['val_accuracy'], label=model_name)\n",
    "    plt.title('Model Accuracy Comparison')\n",
    "    plt.ylabel('Accuracy')\n",
    "    plt.xlabel('Epoch')\n",
    "    plt.legend()\n",
    "\n",
    "    plt.subplot(1, 2, 2)\n",
    "    for model_name, results in model_results.items():\n",
    "        plt.plot(results['history'].history['val_loss'], label=model_name)\n",
    "    plt.title('Model Loss Comparison')\n",
    "    plt.ylabel('Loss')\n",
    "    plt.xlabel('Epoch')\n",
    "    plt.legend()\n",
    "    plt.tight_layout()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-19T10:36:26.045952Z",
     "iopub.status.busy": "2025-02-19T10:36:26.045620Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "--- Training 2d_cnn Model ---\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.10/dist-packages/keras/src/layers/convolutional/base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n",
      "  super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_1\"</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mModel: \"sequential_1\"\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> Layer (type)                         </span>┃<span style=\"font-weight: bold\"> Output Shape                </span>┃<span style=\"font-weight: bold\">         Param # </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n",
       "│ conv2d_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)                    │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">222</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">222</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)        │             <span style=\"color: #00af00; text-decoration-color: #00af00\">896</span> │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ max_pooling2d_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">111</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">111</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)        │               <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ conv2d_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)                    │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">109</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">109</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)        │          <span style=\"color: #00af00; text-decoration-color: #00af00\">18,496</span> │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ max_pooling2d_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">54</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">54</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)          │               <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ global_average_pooling2d_1           │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)                  │               <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GlobalAveragePooling2D</span>)             │                             │                 │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ dense_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)                      │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)                  │           <span style=\"color: #00af00; text-decoration-color: #00af00\">4,160</span> │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ dropout_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>)                  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)                  │               <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ dense_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)                      │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5</span>)                   │             <span style=\"color: #00af00; text-decoration-color: #00af00\">325</span> │\n",
       "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                        \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape               \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m        Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n",
       "│ conv2d_2 (\u001b[38;5;33mConv2D\u001b[0m)                    │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m222\u001b[0m, \u001b[38;5;34m222\u001b[0m, \u001b[38;5;34m32\u001b[0m)        │             \u001b[38;5;34m896\u001b[0m │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ max_pooling2d_2 (\u001b[38;5;33mMaxPooling2D\u001b[0m)       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m111\u001b[0m, \u001b[38;5;34m111\u001b[0m, \u001b[38;5;34m32\u001b[0m)        │               \u001b[38;5;34m0\u001b[0m │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ conv2d_3 (\u001b[38;5;33mConv2D\u001b[0m)                    │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m109\u001b[0m, \u001b[38;5;34m109\u001b[0m, \u001b[38;5;34m64\u001b[0m)        │          \u001b[38;5;34m18,496\u001b[0m │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ max_pooling2d_3 (\u001b[38;5;33mMaxPooling2D\u001b[0m)       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m54\u001b[0m, \u001b[38;5;34m54\u001b[0m, \u001b[38;5;34m64\u001b[0m)          │               \u001b[38;5;34m0\u001b[0m │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ global_average_pooling2d_1           │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m)                  │               \u001b[38;5;34m0\u001b[0m │\n",
       "│ (\u001b[38;5;33mGlobalAveragePooling2D\u001b[0m)             │                             │                 │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ dense_2 (\u001b[38;5;33mDense\u001b[0m)                      │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m)                  │           \u001b[38;5;34m4,160\u001b[0m │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ dropout_1 (\u001b[38;5;33mDropout\u001b[0m)                  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m)                  │               \u001b[38;5;34m0\u001b[0m │\n",
       "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
       "│ dense_3 (\u001b[38;5;33mDense\u001b[0m)                      │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5\u001b[0m)                   │             \u001b[38;5;34m325\u001b[0m │\n",
       "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">23,877</span> (93.27 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m23,877\u001b[0m (93.27 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">23,877</span> (93.27 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m23,877\u001b[0m (93.27 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "\u001b[1m3080/3080\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1485s\u001b[0m 480ms/step - accuracy: 0.8539 - loss: 0.4295 - val_accuracy: 0.9988 - val_loss: 0.0046\n",
      "Epoch 2/10\n",
      "\u001b[1m3080/3080\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1270s\u001b[0m 412ms/step - accuracy: 0.9953 - loss: 0.0194 - val_accuracy: 0.9862 - val_loss: 0.0333\n",
      "Epoch 3/10\n",
      "\u001b[1m1605/3080\u001b[0m \u001b[32m━━━━━━━━━━\u001b[0m\u001b[37m━━━━━━━━━━\u001b[0m \u001b[1m9:08\u001b[0m 372ms/step - accuracy: 0.9983 - loss: 0.0078"
     ]
    }
   ],
   "source": [
    "results = train_all_models(train_df, test_df)\n",
    "plot_model_comparisons(results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.status.busy": "2025-02-19T10:36:16.488334Z",
     "iopub.status.idle": "2025-02-19T10:36:16.488645Z",
     "shell.execute_reply": "2025-02-19T10:36:16.488481Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "from tensorflow.keras.models import load_model\n",
    "import numpy as np\n",
    "\n",
    "model_2d_cnn = build_2d_cnn((224, 224, 3), len(classes_to_include))  \n",
    "model_vgg16 = build_vgg16((224, 224, 3), len(classes_to_include))    \n",
    "model_vgg19 = build_vgg19((224, 224, 3), len(classes_to_include))    \n",
    "model_resnet50 = build_resnet50((224, 224, 3), len(classes_to_include)) \n",
    "\n",
    "# Assuming models are trained, load their weights if needed:\n",
    "# model_2d_cnn.load_weights('model_2d_cnn.h5')\n",
    "# model_vgg16.load_weights('model_vgg16.h5')\n",
    "# model_vgg19.load_weights('model_vgg19.h5')\n",
    "# model_resnet50.load_weights('model_resnet50.h5')\n",
    "\n",
    "def ensemble_predict(models, test_generator, weights=None):\n",
    "    num_models = len(models)\n",
    "    num_samples = test_generator.samples\n",
    "    num_classes = len(classes_to_include)\n",
    "\n",
    "    ensemble_preds = np.zeros((num_samples, num_classes))\n",
    "    if weights is None:\n",
    "        weights = [1 / num_models] * num_models\n",
    "\n",
    "    for model, weight in zip(models, weights):\n",
    "        preds = model.predict(test_generator, verbose=0)\n",
    "        ensemble_preds += weight * preds\n",
    "\n",
    "    return ensemble_preds\n",
    "\n",
    "# Evaluate ensemble predictions\n",
    "models = [model_2d_cnn, model_vgg16, model_vgg19, model_resnet50]\n",
    "weights = [0.25, 0.25, 0.25, 0.25]  # Equal weights for simplicity\n",
    "ensemble_preds = ensemble_predict(models, test_df, weights)\n",
    "ensemble_classes = np.argmax(ensemble_preds, axis=1)\n",
    "true_classes = test_df.classes\n",
    "\n",
    "# Accuracy\n",
    "accuracy = np.sum(ensemble_classes == true_classes) / len(true_classes)\n",
    "print(f\"Ensemble Accuracy: {accuracy:.2f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "trusted": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kaggle": {
   "accelerator": "nvidiaTeslaT4",
   "dataSources": [
    {
     "datasetId": 875281,
     "sourceId": 1490938,
     "sourceType": "datasetVersion"
    }
   ],
   "dockerImageVersionId": 30887,
   "isGpuEnabled": true,
   "isInternetEnabled": true,
   "language": "python",
   "sourceType": "notebook"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
